package com.easycms.framework.shiro.realm;

import cn.hutool.core.util.ObjectUtil;
import com.easycms.framework.shiro.UserOwnInfo;
import com.easycms.framework.shiro.stateless.StatelessToken;
import com.easycms.web.system.service.SysRoleService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.AllowAllCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;

/**
 * @author yushuo
 * @className
 * @descripton TODO
 * @date 2021/2/4 11:22
 **/
public class TokenRealm extends AuthorizingRealm {

    @Autowired
    private SysRoleService roleService;

    public TokenRealm(){
        super(new AllowAllCredentialsMatcher());
        setAuthenticationTokenClass(BearerToken.class);
    }

    /**
     * 只支持selfLoginToken
     *
     * @param token
     * @return
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof StatelessToken;
    }

    /**
     * @MethodName doGetAuthenticationInfo
     * @Description 登录认证,认证配置类，登录的时候才会执行
     * @Param [authenticationToken]
     * @Return AuthenticationInfo
     * @Author yushuo
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        //System.err.println("doGetAuthenticationInfo:"+ LocalDateTime.now().toString());
        if(ObjectUtil.isEmpty(token.getPrincipal())){
            throw new AuthenticationException("用户信息已过期，请重新登录");
        }
        StatelessToken userToken = (StatelessToken) token;
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(userToken.getUserCookie(),
                userToken.getCredentials(),
                userToken.getUserName());
        return authenticationInfo;
    }

    /**
     * @MethodName doGetAuthorizationInfo
     * @Description 授权。权限配置类，每次请求都会执行匹配权限
     * @Param [principalCollection]
     * @Return AuthorizationInfo
     * @Author yushuo
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//        System.err.println("doGetAuthorizationInfo:"+ LocalDateTime.now().toString());
//
        UserOwnInfo userOwnInfo = (UserOwnInfo)principalCollection.getPrimaryPrincipal();
//        System.err.println("doGetAuthorizationInfo userOwnInfo:"+ userOwnInfo);
        // 角色列表
        Set<String> roles = new HashSet<>();
        // 功能列表
        Set<String> permissions = new HashSet<String>();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        // 管理员拥有所有权限
        if (userOwnInfo.isAdmin()) {
            info.addRole("admin");
            info.addStringPermission("*:*:*");
        } else {
            roles.add(userOwnInfo.getRoleId().toString());
             //获取角色权限
            permissions=roleService.getPermissionTags(userOwnInfo.getRoleId());
            // 角色加入AuthorizationInfo认证对象
            info.setRoles(roles);
            // 权限加入AuthorizationInfo认证对象
            info.setStringPermissions(permissions);
        }
        return info;
    }

}
